#include "lcd.h"


 
uint16_t ltdc_layer0[LTDC_WIDTH][LTDC_HEIGHT] __attribute__((section(".GRAM_ADD")));


uint32_t LCD_ReadPoint(uint16_t x, uint16_t y)
{
    return *(uint16_t*)((uint32_t)ltdc_layer0[0] + 2 * (LTDC_WIDTH * y + x));
}
 

void LCD_DrawPoint(uint16_t x, uint16_t y, uint32_t color)
{
    *(uint16_t*)((uint32_t)ltdc_layer0[0] + 2 * (LTDC_WIDTH * y + x)) = color;
}


//单色填充
//寄存器到存储器方式(注意在cube中开启DMA2D，同时注意 寄存器到存储器 方式对应)
void LCD_COLOR_Fill(uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey, uint16_t color)
{
    uint32_t timeout = 0;
    uint32_t addr = ((uint32_t)ltdc_layer0[0] + 2 * (LTDC_WIDTH * sy + sx));
    uint16_t offline = LTDC_WIDTH - (ex - sx + 1);

	DMA2D->CR&=~(DMA2D_CR_START);
	DMA2D->OOR=offline;

	DMA2D->OMAR=addr;
	DMA2D->NLR=(ey-sy+1)|((ex-sx+1)<<16);
	DMA2D->OCOLR=color;
	DMA2D->CR|=DMA2D_CR_START;
	while((DMA2D->ISR&(DMA2D_FLAG_TC))==0)
	{
		timeout++;
		if(timeout>0X1FFFFF)break;
	}
	DMA2D->IFCR|=DMA2D_FLAG_TC;
}



//填充
//存储器到存储器方式(注意在cube中开启DMA2D，同时注意 存储器到存储器 方式对应)(注意移植LVGL，Emwin等gui后需要用这种方式)
void LCD_Fill(uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey, uint16_t* color)
{
    uint32_t timeout = 0;
    uint32_t addr = ((uint32_t)ltdc_layer0[0] + 2 * (LTDC_WIDTH * sy + sx));
    uint16_t offline = LTDC_WIDTH - (ex - sx + 1);

	DMA2D->CR      = 0x00000000UL | (1 << 9);
	// 源地址
	DMA2D->FGMAR   = (uint32_t)color;
	// 目标地址
	DMA2D->OMAR    = (uint32_t)(uint16_t *)addr;
	// 输入偏移
	DMA2D->FGOR    = 0;
	// 输出偏移
	DMA2D->OOR     = offline;
	DMA2D->NLR     = (ey-sy+1)|((ex-sx+1)<<16);
	/* 启动传输 */
	DMA2D->CR   |= DMA2D_CR_START;
	/* 等待DMA2D传输完成 */
	while (DMA2D->CR & DMA2D_CR_START)
	{
		timeout++;
		if(timeout>0X1FFFFF)break;
	}
}




